/*
 * Created by Wildish on 2016-11-11
 *
 * Contact me with keithknight@qq.com
 *
 * Copyright (c) 2016 Wildish
 */

package com.wildish.hybridframework.jsbinding.proxy;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.webkit.WebView;
import android.widget.Toast;

import com.chinark.apppickimagev3.ui.PhotoWallActivity;
import com.chinark.apppickimagev3.utils.ImagePickResult;
import com.chinark.apppickimagev3.utils.ScreenUtils;
import com.wildish.hybridframework.R;
import com.wildish.hybridframework.activity.ViewPagerActivity;
import com.wildish.hybridframework.activity.WebViewActivity;
import com.wildish.hybridframework.core.HybridGlobal;
import com.wildish.hybridframework.jsbinding.webview.JsHelper;
import com.wildish.hybridframework.jsbinding.webview.WebViewBundle;
import com.wildish.hybridframework.scanqrcode.CaptureActivity;
import com.wildish.hybridframework.utils.audio.MediaPlayerHelper;
import com.wildish.hybridframework.utils.audio.SoundItem;
import com.wildish.hybridframework.utils.file.FileUtil;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;

public class DefaultHybridProxy extends BaseHybridProxy {
    // 页面跳转通用
    public static final String PROXY_DEFAULT_KEY_BACKWARD = "backward";
    public static final String PROXY_DEFAULT_KEY_NEWWIN = "newwin";
    public static final String PROXY_DEFAULT_KEY_CANCEL = "cancel";
    public static final String PROXY_DEFAULT_KEY_CANCELALL = "cancel_all";
    // 通用功能
    public static final String PROXY_DEFAULT_KEY_TAKE_PHOTO = "take_photo";
    public static final String PROXY_DEFAULT_KEY_SHOWIMAGES = "show_images";
    public static final String PROXY_DEFAULT_KEY_TAKEALBUM = "take_album";
    public static final String PROXY_DEFAULT_KEY_QRCODE = "scanqrcode";
    public static final String PROXY_DEFAULT_KEY_TAKE_CALL = "take_call";
    public static final String PROXY_DEFAULT_KEY_TEMP_FOLDER_SIZE = "temp_folder_size";
    public static final String PROXY_DEFAULT_KEY_CLEAR_TEMP_FOLDER = "clear_temp_folder";
    public static final String PROXY_DEFAULT_KEY_LOAD_AUDIO = "load_audio";
    public static final String PROXY_DEFAULT_KEY_PLAY_AUDIO = "play_audio";
    public static final String PROXY_DEFAULT_KEY_CLOSE_AUDIO = "close_audio";
    public static final String PROXY_DEFAULT_KEY_OPEN_AUDIO = "open_audio";
    public static final String PROXY_DEFAULT_KEY_RELEASE_AUDIO = "release_audio";
    public static final String PROXY_DEFAULT_KEY_GET_DATA = "get_data";

    private static final int REQUEST_CODE_TAKE_PHOTO = 1;
    private static final int REQUEST_CODE_SCANQRCODE = 2;

    private static final int TAKEFOCUS_CODE_DEFAULT = 0;
    private static final int TAKEFOCUS_CODE_TAKE_ALBUM = 1;
    private String photoPath;


    public DefaultHybridProxy(String key) {
        super(key);
    }

    private Context context;
    private int onTakeFocusKey = -1;

    @Override
    public void execute(Context context, String action, JSONObject params) {
        this.context = context;
        String temAction = (action.contains(".") ? action.substring(0, action.indexOf(".")): action);
        switch (temAction) {
            case PROXY_DEFAULT_KEY_TAKE_PHOTO:
                doTakePhoto();
                break;
            case PROXY_DEFAULT_KEY_BACKWARD:
                doBackward();
                break;
            case PROXY_DEFAULT_KEY_NEWWIN:
                showNewWin(params);
                break;
            case PROXY_DEFAULT_KEY_CANCEL:
                cancelWebview(params);
                break;
            case PROXY_DEFAULT_KEY_CANCELALL:
                cancelAllWebview(params);
                break;
            case PROXY_DEFAULT_KEY_SHOWIMAGES:
                showImages(params);
                break;
            case PROXY_DEFAULT_KEY_TAKEALBUM:
                takeAlbum();
                break;
            case PROXY_DEFAULT_KEY_QRCODE:
                goScanQRCode();
                break;
            case PROXY_DEFAULT_KEY_LOAD_AUDIO:
                doLoadAudio(params);
                break;
            case PROXY_DEFAULT_KEY_PLAY_AUDIO:
                playAudio(params);
                break;
            case PROXY_DEFAULT_KEY_CLOSE_AUDIO:
                closeAudio();
                break;
            case PROXY_DEFAULT_KEY_OPEN_AUDIO:
                openAudio();
                break;
            case PROXY_DEFAULT_KEY_RELEASE_AUDIO:
                releaseAllAudio();
                break;
            case PROXY_DEFAULT_KEY_TAKE_CALL:
                String phone = params.optString("phone");
                takeCall(phone);
                break;
            case PROXY_DEFAULT_KEY_TEMP_FOLDER_SIZE:
                long filesize = FileUtil.fileSize(HybridGlobal.getTempFolder());
                String sizeResult = "{\"success\": true, \"filesize\": \"" + filesize + "\"}";
                super.sendToWebview(key, PROXY_DEFAULT_KEY_TEMP_FOLDER_SIZE, sizeResult);
                break;
            case PROXY_DEFAULT_KEY_CLEAR_TEMP_FOLDER:
                boolean tempFlag = FileUtil.delDir(HybridGlobal.getTempFolder());
                super.sendToWebview(key, PROXY_DEFAULT_KEY_CLEAR_TEMP_FOLDER, "{\"success\": " + tempFlag + "}");
                break;
            case PROXY_DEFAULT_KEY_GET_DATA:
                doGetData(action, params);
                break;
            default:
                doCommonError();
        }
    }

    private void doGetData(final String action, final JSONObject parameter) {
        HybridGlobal.pool.submit(new Runnable() {
            @Override
            public void run() {
                Message msg = new Message();
                msg.what = MSG_GETDATA;
                Bundle bundle = new Bundle();
                bundle.putString("action", action);
                if(dataHandler == null) {
                    bundle.putString("result", DataHandler.COMMON_FAIL_NO_HANDLER);
                } else {
                    String result = dataHandler.getData(parameter);
                    bundle.putString("result", result);
                }
                msg.setData(bundle);
                handler.sendMessage(msg);
            }
        });
    }

    private void takeAlbum() {
        HybridGlobal.getInstance().updateGallery();
        ScreenUtils.initScreen(HybridGlobal.getCurrentWebViewContext());
        Intent intent = new Intent(HybridGlobal.getCurrentWebViewContext(), PhotoWallActivity.class);
        this.onTakeFocusKey = TAKEFOCUS_CODE_TAKE_ALBUM;
        HybridProxyManager.getInstance().startActivity(this, intent);
    }

    private void takeCall(String phone) {
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:" + phone));
        HybridProxyManager.getInstance().startActivity(null, intent);
    }

    private void showImages(JSONObject params) {
        try {
            JSONArray imageArray = params.optJSONArray("images");
            int index = params.optInt("index", 0);
            if (imageArray.length() > 0) {
                JSONArray finalImageArray = new JSONArray();
                for (int i = 0; i != imageArray.length(); i++) {
                    String url = imageArray.getJSONObject(i).optString("url", "");
                    if (StringUtils.isBlank(url)) {
                        continue;
                    }
                    finalImageArray.put(imageArray.getJSONObject(i));
                }
                Intent imageIntent = new Intent(HybridGlobal.getCurrentWebViewContext(), ViewPagerActivity.class);
                imageIntent.putExtra("imageList", imageArray.toString());
                imageIntent.putExtra("index", index);
                HybridProxyManager.getInstance().startActivity(null, imageIntent);
            }
        } catch (Exception e) {
            HybridGlobal.logger.log(e);
        }
    }

    private void goScanQRCode() {
        Intent intent = new Intent(HybridGlobal.getCurrentWebViewContext(), CaptureActivity.class);
        HybridProxyManager.getInstance().startActivityForResult(this, intent, REQUEST_CODE_SCANQRCODE);
    }

    private void doLoadAudio(JSONObject params) {
        MediaPlayerHelper helper = HybridGlobal.getInstance().getSoundHelper();
        String src = params.optString("src");
        String key = params.optString("key");
        String result = "";
        try {
            if (StringUtils.isNotBlank(src) && StringUtils.isNotBlank(key)) {
                SoundItem soundItem = new SoundItem();
                soundItem.setSoundPath(params.optString("src"));
                helper.loadSoundByPath(params.optString("key"), soundItem);

                params.put("success", true);
            } else {
                params.put("success", false);
            }
            result = params.toString();
        } catch (Exception e) {
            HybridGlobal.logger.log(e);
            result = "{\"success\": false}";
        }
        super.sendToWebview(this.key, PROXY_DEFAULT_KEY_LOAD_AUDIO, result);
    }

    private void playAudio(JSONObject params) {
        String playKey = params.optString("key");
        String status = params.optString("status");
        if (StringUtils.isNotBlank(playKey) && StringUtils.isNotBlank(status)) {
            HybridGlobal.getInstance().getSoundHelper().playSound(playKey, status);
        }
    }

    private void closeAudio() {
        HybridGlobal.getInstance().closeMediaVoice();
    }

    private void openAudio() {
        HybridGlobal.getInstance().openMediaVoice();
    }

    private void releaseAllAudio() {
        HybridGlobal.getInstance().getSoundHelper().releaseAll();
    }

    private void doCommonError() {

    }

    @Override
    public void release() {
        super.sendToWebview(key, PROXY_DEFAULT_KEY_TAKE_PHOTO, COMMON_FAIL_NO_SUCH_METHOD);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_CODE_TAKE_PHOTO) {
            File file = new File(photoPath);
            String resultStr;
            try {
                JSONObject result = new JSONObject();
                if (!file.exists()) {
                    result.put("success", false);
                    result.put("filepath", "");
                } else {
                    // 添加压缩图片逻辑
                    File destFile = new File(generateTempPhotoPath());
                    FileUtil.compressImage(file, destFile, 70);
                    result.put("success", true);
                    result.put("filepath", destFile.getAbsolutePath());
                }
                resultStr = result.toString();
            } catch (Exception e) {
                HybridGlobal.logger.log(e);
                resultStr = COMMON_FAIL_RESP;
            }
            super.sendToWebview(key, PROXY_DEFAULT_KEY_TAKE_PHOTO, resultStr);
        } else if (requestCode == REQUEST_CODE_SCANQRCODE) {
            String code = data.getStringExtra("code");
            String result = "{\"success\": false}";
            if (StringUtils.isNotBlank(code)) {
                result = "{\"success\": true, \"code\": \"" + code + "\"}";
            }
            super.sendToWebview(key, PROXY_DEFAULT_KEY_QRCODE, result);
        }
    }

    @Override
    public void onTakeFocus() {
        super.onTakeFocus();
        if(this.onTakeFocusKey == TAKEFOCUS_CODE_TAKE_ALBUM) {
            // 处理图片选择
            this.onTakeFocusKey = TAKEFOCUS_CODE_DEFAULT;
            JSONArray result = new JSONArray();
            try {
                ArrayList<String> paths = ImagePickResult.getInstance().getImageList();
                if (paths.size() > 0) {
                    //添加，去重
                    ArrayList<String> imagePathList = new ArrayList<>();
                    for (String path : paths) {
                        if (!imagePathList.contains(path)) {
                            imagePathList.add(path);
                        }
                    }
                    for (String path : imagePathList) {
                        JSONObject item = new JSONObject();

                        // 添加压缩图片
                        File destFile = new File(generateTempPhotoPath());
                        FileUtil.compressImage(new File(path), destFile, 70);

                        item.put("filepath", destFile.getAbsolutePath());
                        result.put(item);
                    }
                }
                ImagePickResult.getInstance().clearImageList();
            } catch (Exception e) {
                HybridGlobal.logger.log(e);
            }
            super.sendToWebview(key, PROXY_DEFAULT_KEY_TAKEALBUM, result.toString());
        } else {
            Bundle bundle = WebViewBundle.getInstance().getBundle();
            if (bundle != null && !bundle.isEmpty()) {
                String params = bundle.getString(WebViewBundle.BUNDLE_PARAMS, "{}");
                WebViewBundle.getInstance().clearBundle();
                HybridGlobal.getCurrentWebView().loadUrl(JsHelper.createCallback(HybridGlobal.PROXY_HF_DEFAULT, DefaultHybridProxy.PROXY_DEFAULT_KEY_NEWWIN, params));
            }
        }
    }

    private void doTakePhoto() {
        Intent intent = new Intent();
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        photoPath = generateTempPhotoPath();
        File file = new File(photoPath);
        try{
            file.deleteOnExit();
            file.getParentFile().mkdirs();
            file.createNewFile();
            Uri fileUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

            HybridProxyManager.getInstance().startActivityForResult(this, intent, REQUEST_CODE_TAKE_PHOTO);
        } catch (Exception e) {
            super.sendToWebview(key, PROXY_DEFAULT_KEY_TAKE_PHOTO, COMMON_FAIL_RESP);
        }
    }

    private void doBackward() {
        final WebView currWebview = HybridGlobal.getCurrentWebView();
        currWebview.post(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = MSG_GOBACKWARD;
                message.obj = currWebview.canGoBack();
                handler.sendMessage(message);
            }
        });
    }

    private void showNewWin(JSONObject params) {
        Bundle webViewBundle = new Bundle();
        String typeTag = params.optString("type_tag", "");
        Boolean showNativeTopbar = params.optBoolean("native_topbar", false);
        String project = params.optString("project", "");
        String page = params.optString("page", "");
        String paramsData = params.optString("params", "{}");
        String title = params.optString("title", "");

        if (StringUtils.isBlank(project) || StringUtils.isBlank(typeTag) || StringUtils.isBlank(page)) {
            Context context = HybridGlobal.webViewStack.peek().getContext();
            Toast.makeText(context, R.string.error_newwin_params, Toast.LENGTH_SHORT).show();
        } else {
            webViewBundle.putString("typeTag", typeTag);
            webViewBundle.putBoolean("showTopbar", showNativeTopbar);
            webViewBundle.putString("linkurl", page);
            webViewBundle.putString("title", title);
            webViewBundle.putString("page", page);
            webViewBundle.putString("paramsdata", paramsData);
            webViewBundle.putString("project", project);

            Intent webViewIntent = new Intent(HybridGlobal.getCurrentWebViewContext(), WebViewActivity.class);
            webViewIntent.putExtras(webViewBundle);
            HybridProxyManager.getInstance().startActivity(this, webViewIntent);
        }
    }

    private void cancelAllWebview(JSONObject params) {
        WebViewBundle.getInstance().setBundle(params.toString());
        while (HybridGlobal.webViewStack.size() > 1) {
            Activity context = HybridGlobal.getCurrentWebViewContext();
            if (context != null) {
                context.finish();
            }
            HybridGlobal.webViewStack.pop();
        }
    }

    private void cancelWebview(JSONObject params) {
        WebViewBundle.getInstance().setBundle(params.toString());
        Activity context = HybridGlobal.getCurrentWebViewContext();
        if (context != null) {
            context.finish();
        }
        HybridGlobal.webViewStack.pop();
    }

    private String generateTempPhotoPath() {
        return HybridGlobal.getTempFolder().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg";
    }

    private static final int MSG_GOBACKWARD = 1;
    private static final int MSG_GETDATA = 2;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_GOBACKWARD:
                    DefaultHybridProxy.super.sendToWebview(key, PROXY_DEFAULT_KEY_BACKWARD, String.valueOf(msg.obj));
                    break;
                case MSG_GETDATA:
                    Bundle bundle = msg.getData();
                    String action = bundle.getString("action");
                    String result = bundle.getString("result");
                    DefaultHybridProxy.super.sendToWebview(key, action, result);
                    break;
            }
        }
    };
}
